import logging
import os.path
import time

from selenium import webdriver
from selenium.common import  NoSuchElementException
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

from constants.constant import CHROME_BIN_PATH, CHROME_DRIVER_PATH, USER_DATA_PATH, URL_MY_PROJECT, CREATE_PROJECT_URL
from utils.FileUtil import save_config_to_properties


def loginAgcConnect(appInfo, userConfig):
    service = Service(executable_path= CHROME_DRIVER_PATH)
    print(CHROME_DRIVER_PATH)

    waitTime = 3
    if not os.path.exists(USER_DATA_PATH):
        waitTime = 60

    options = webdriver.ChromeOptions()
    options.binary_location = CHROME_BIN_PATH
    options.add_argument("--head")
    options.add_argument("--start-maximized")
    options.add_argument("--disable-gpu")
    options.add_argument("--no-sandbox")
    options.add_argument("--user-data-dir=" + USER_DATA_PATH)
    options.add_experimental_option("prefs" , {
        "download.default_directory":  userConfig["download_path"] + "\\" + str(appInfo.order_id) + "-" + appInfo.app_name + "\\json文件\\AGC配置",
        "download.prompt_for_download": False,
        "download.directory_upgrade": True,
        "safebrowsing.enabled": True
    })
    driver = webdriver.Chrome(service=service, options=options)

    try:
        driver.implicitly_wait(20)
        driver.get(URL_MY_PROJECT)
        time.sleep(3)

        inputForUserId = driver.find_element(By.XPATH, "//*[@class='hwid-input userAccount']")
        inputForUserId.clear()
        inputForUserId.send_keys(userConfig["user_name"])

        inputForPassword = driver.find_element(By.XPATH, "//*[@class = 'hwid-input hwid-input-pwd']")
        inputForPassword.clear()
        inputForPassword.send_keys(userConfig["user_password"])

        loginButton = driver.find_element(By.XPATH, "//span[text() = '登录']")
        loginButton.click()
        time.sleep(waitTime)

        return driver
    except Exception as e:
        logging.error(e)
        logging.error(appInfo.app_name + ":登录失败: 需要检查网络是否通常或者等待几分钟后再尝试")
        return  None


def checkAndChangeSubject(driver, appInfo):
    try:
        time.sleep(2)
        userBox = driver.find_element(By.CLASS_NAME, "user-box")
        userBox.click()
        time.sleep(2)

        selectedSubject = driver.find_element(By.CSS_SELECTOR, 'li.team-list-item.selected div').text
        if appInfo.subject_name != selectedSubject:
            logging.info(appInfo.app_name + ":当前登录主体与游戏主体不同,进行切换主体")

        shouldSelectedSubjectDiv = driver.find_element(By.XPATH, "//div[text() = '" + appInfo.subject_name + "']")
        shouldSelectedSubjectDiv.click()
        time.sleep(3)

        driver.get(URL_MY_PROJECT)

        time.sleep(3)
    except Exception:
        logging.info(appInfo.app_name + ":切换主体失败")
        raise

def deleteApp(driver, appInfo):
    try:
        projectDiv = driver.find_element(By.XPATH, "//span[text()='" + appInfo.app_name +"']")
        time.sleep(2)
        projectDiv.click()
        time.sleep(3)

        switchToNewIframe(driver)
        deleteAppButton = driver.find_element(By.XPATH, "//span[text()='删除应用']")
        deleteAppButton.click()
        time.sleep(1)

        confirmButton = driver.find_element(By.XPATH, "//span[text()= '确认']")
        confirmButton.click()
        time.sleep(3)
    except Exception:
        logging.info(appInfo.app_name +"：未创建应用：请检查包名是否重复")
        time.sleep(2)



def directToCreatePage(driver, appInfo, projectExistFlag):
    try:
        if projectExistFlag:
            projectDiv = driver.find_element(By.XPATH, "//div[text()='" + appInfo.app_name + "-鸿蒙" + "']")
            time.sleep(3)
            projectDiv.click()
            time.sleep(3)

        switchToNewIframe(driver)
        addAppButton = driver.find_element(By.XPATH, "//span[text()  ='添加应用']")
        addAppButton.click()
        time.sleep(3)

        switchToNewIframe(driver)
        hapRadio = driver.find_element(By.XPATH, "//span[text() = 'APP(HarmonyOS)']")
        hapRadio.click()
        time.sleep(3)

        appIdLink = driver.find_element(By.ID, 'appIdLink')
        appIdLink.click()
        time.sleep(3)
    except Exception:
        logging.error(appInfo.app_name + ":导航创建app页失败")
        raise

def createApp(driver, appInfo):
    try:
        switchToNewIframe(driver)
        inputForAppName = driver.find_element(By.XPATH, "//input[contains(@placeholder, '填写新应用名称')]")
        inputForAppName.clear()
        inputForAppName.send_keys(appInfo.app_name)
        time.sleep(1)

        inputForBuddleName = driver.find_element(By.XPATH, "//input[contains(@placeholder, '应用包名')]")
        inputForBuddleName.clear()
        inputForBuddleName.send_keys(appInfo.package_name)
        time.sleep(1)

        gameRadio = driver.find_element(By.XPATH, "//span[text() = '游戏' and contains(@class, 'el-radio__label')]")
        gameRadio.click()
        time.sleep(2)

        nextButton = driver.find_element(By.XPATH, "//span[text()= '下一步']")
        nextButton.click()
        time.sleep(3)

        switchToNewIframe(driver)
        confirmButton = driver.find_element(By.XPATH , "//button[@aria-disabled='false' and span[text()= '确认']]")
        confirmButton.click()
        time.sleep(3)

        switchToNewIframe(driver)
        confirmButton = driver.find_element(By.XPATH, "//button[@aria-disabled='false' and span[text()= '确认']]")
        confirmButton.click()
        logging.info(appInfo.app_name + ":创建app完成")
        time.sleep(3)
    except Exception:
        logging.error(appInfo.app_name + ":创建app失败：请确保包名未重复使用")
        raise



def isExistProject(driver, appInfo):
    try:
        projectDiv = driver.find_element(By.XPATH, "//div[text()='" + appInfo.app_name + "-鸿蒙" + "']")
        return True
    except NoSuchElementException:
        return False


def addFingerprint(driver, appInfo):
    try:
        projectDiv = driver.find_element(By.XPATH, "//div[text()='" + appInfo.app_name + "-鸿蒙" + "']")
        time.sleep(3)
        projectDiv.click()
        time.sleep(3)

        switchToNewIframe(driver)

        addFingerprintButton = driver.find_element(By.XPATH, "//span[text() = '添加证书指纹']")
        addFingerprintButton.click()
        time.sleep(2)
        inputForFingerprint = driver.find_element(By.XPATH, "//input[contains(@placeholder, '输入SHA256证书/公钥指纹')]")
        inputForFingerprint.clear()
        inputForFingerprint.send_keys(appInfo.fingerprint1)

        time.sleep(1)

        confirmButton = driver.find_element(By.XPATH, "//span[text() = '保存' and not(@style)]")
        confirmButton.click()
        logging.info(appInfo.app_name + ":添加指纹1完成")
        time.sleep(3)

        addFingerprintButton.click()
        time.sleep(2)
        inputForFingerprint = driver.find_element(By.XPATH, "//input[contains(@placeholder, '输入SHA256证书/公钥指纹')]")
        inputForFingerprint.clear()
        inputForFingerprint.send_keys(appInfo.fingerprint2)

        time.sleep(1)

        confirmButton = driver.find_element(By.XPATH, "//span[text() = '保存' and not(@style)]")
        confirmButton.click()
        logging.info(appInfo.app_name + ":添加指纹2完成")
        time.sleep(3)

    except Exception:
        logging.error(appInfo.app_name +"：添加指纹失败：请检查网络状态")
        raise

def addGameInfo(driver, appInfo):
    try:
        driver.switch_to.default_content()
        gameServiceButton = driver.find_element(By.XPATH, "//span[text() = '游戏服务']")
        ul_element = gameServiceButton.find_element(By.XPATH, "./ancestor::ul[1]")
        style_value = ul_element.get_attribute("style")
        if style_value and 'display: none' in style_value:
            buildButton = driver.find_element(By.XPATH, "//span[text() = '构建']")
            buildButton.click()
            time.sleep(1)
        gameServiceButton.click()
        time.sleep(4)

        switchToNewIframe(driver)

        addConfigButton = driver.find_element(By.XPATH, "//span[text() = '新增配置']")
        addConfigButton.click()
        time.sleep(1)

        inputForChooseGame = driver.find_element(By.XPATH, "//label[text() = 'HarmonyOS NEXT游戏']")
        inputForChooseGame.click()
        time.sleep(1)
        harmonyOsNextContent = appInfo.app_name + " " + appInfo.app_id
        gameChooseButton = driver.find_element(By.XPATH, "//span[starts-with(text(), '"+ harmonyOsNextContent + "')]")
        gameChooseButton.click()
        time.sleep(1)
        logging.info(appInfo.app_name + ":游戏信息映射成功")
    except Exception:
        logging.error(appInfo.app_name + ":游戏信息映射失败")
        raise

    try:
        try:
            inputForChooseGame = driver.find_element(By.XPATH, "//label[text() = 'HarmonyOS游戏']")
            inputForChooseGame.click()
            time.sleep(1)

            gameChooseButton = driver.find_element(By.XPATH, "//span[text() = '不涉及']")
        except Exception :
            # todo revise
            gameChooseButton = driver.find_element(By.XPATH, "//span[starts-with(normalize-space(), '" + appInfo.app_name + "') and substring(normalize-space(), string-length(normalize-space()) - 1) = '手机' and not(starts-with(normalize-space(), '" + harmonyOsNextContent + "'))]")
        gameChooseButton.click()
        time.sleep(1)

        singleGameRadio = driver.find_element(By.XPATH, "//span[text() = '是' and contains(@class, 'el-radio__label')]")
        singleGameRadio.click()
        time.sleep(1)

        nextButton = driver.find_element(By.XPATH, "//span[text() = '下一步' and not(@style)]")
        nextButton.click()
        time.sleep(3)

        confirmButton = driver.find_element(By.XPATH, "//span[text()= '确定' and not(@style)]")
        confirmButton.click()
        time.sleep(5)

        try:
            titleButton = driver.find_element(By.XPATH, "//p[text() = '该开发者名下还有如下相同游戏名称的游戏：']")
            confirmButton = driver.find_element(By.XPATH, "//span[text()= '取消']/parent::button/following-sibling::button")
            confirmButton.click()
            time.sleep(5)
        except NoSuchElementException:
            logging.info(appInfo.app_name + "：第一次配置")
        logging.info(appInfo.app_name + ":游戏信息配置成功")
    except Exception :
        logging.error(appInfo.app_name + ":游戏信息配置失败")
        raise


def createProject(driver, appInfo):
    try:
        time.sleep(2)
        driver.get(CREATE_PROJECT_URL)
        time.sleep(2)

        inputForProjectName = driver.find_element(By.CLASS_NAME, "el-input__inner")
        inputForProjectName.send_keys(appInfo.app_name + "-鸿蒙")
        time.sleep(2)

        submitProjectButton = driver.find_element(By.XPATH, "//span[text() = '完成']")
        submitProjectButton.click()
        time.sleep(3)
        return True
    except Exception:
        logging.error(appInfo.app_name + ":创建项目失败")
        raise


def addProfile(driver, appInfo, profileName):
    try:
        time.sleep(2)

        driver.switch_to.default_content()
        profileButton = driver.find_element(By.XPATH, "//span[text()= 'Profile']")
        profileButton.click()
        time.sleep(3)

        switchToNewIframe(driver)

        addButton = driver.find_element(By.XPATH, "//span[text()='添加']")
        addButton.click()
        time.sleep(3)

        appChooseButton = driver.find_element(By.XPATH, "//input[contains(@placeholder, '请选择应用名称')]")
        appChooseButton.click()
        time.sleep(2)
        xpath = f"//span[starts-with(., '{appInfo.app_name} --')]"
        appChooseButton = driver.find_element(By.XPATH, xpath)
        appChooseButton.click()

        inputForProfileName = driver.find_element(By.XPATH, "//input[contains(@placeholder, '请输入内容')]")
        inputForProfileName.clear()
        inputForProfileName.send_keys(profileName)

        profileType = "调试" if profileName == "agc_debug" else "发布"
        typeRadio = driver.find_element(By.XPATH, "//span[text()='" + profileType + "' and contains(@class, 'el-radio__label')]")
        typeRadio.click()

        certificate_name = appInfo.certificate_debug_name if profileName == "agc_debug" else appInfo.certificate_release_name
        profileOpenWindowButton = driver.find_element(By.XPATH, "//div[normalize-space()= '选择证书：']/following-sibling::div[1]//Button")
        profileOpenWindowButton.click()
        time.sleep(2)
        profileChooseButton = driver.find_element(By.XPATH, "//tr[.//div[normalize-space()='" + certificate_name + "']]//label")
        profileChooseButton.click()
        time.sleep(2)
        profileConfirmButton = driver.find_element(By.XPATH, "//div[@aria-label='选择证书']//span[text()='确定']")
        profileConfirmButton.click()
        time.sleep(2)

        if profileName == "agc_debug":
            deviceOpenWindowButton = driver.find_element(By.XPATH, "//div[normalize-space()= '选择设备：']/following-sibling::div[1]//Button")
            deviceOpenWindowButton.click()
            inputForSearchDevice = driver.find_element(By.XPATH, "//input[contains(@placeholder, '搜索设备')]")
            inputForSearchDevice.clear()
            inputForSearchDevice.send_keys(appInfo.device_name)
            time.sleep(2)
            deviceChooseButton = driver.find_element(By.XPATH, "//tr[.//div[normalize-space()='" + appInfo.device_name + "']]//label")
            deviceChooseButton.click()
            deviceConfirmButton = driver.find_element(By.XPATH, "//div[@aria-label='选择设备']//span[text()='确定']")
            deviceConfirmButton.click()
            time.sleep(2)
        permissionRadio = driver.find_element(By.XPATH, "//span[text()='受限ACL权限（HarmonyOS API9及以上）']")
        permissionRadio.click()
        time.sleep(2)

        addButton = driver.find_element(By.XPATH, "//span[text()='添加']")
        addButton.click()
        time.sleep(3)

        confirmButton = driver.find_element(By.XPATH, "//span[text()= '确认']")
        confirmButton.click()
        time.sleep(3)
        logging.info(appInfo.app_name + (":新增agc_debug证书完成" if profileName == "agc_debug" else ":新增agc_release证书完成"))
    except Exception:
        logging.error(appInfo.app_name + (":新增agc_debug证书失败" if profileName == "agc_debug" else ":新增agc_release证书失败"))




def downloadProfile(driver, appInfo, profileName):
    try:
        time.sleep(3)
        driver.switch_to.default_content()
        profileButton = driver.find_element(By.XPATH, "//span[text() = 'Profile']")
        profileButton.click()
        time.sleep(3)

        switchToNewIframe(driver)

        xpath = f"""
        //tr[
            td[1]//div[normalize-space()='{profileName}'] and
            td[5]//div[normalize-space()='{appInfo.app_name}']
        ]//span[text()= '下载']
        """
        downloadButton = driver.find_element(By.XPATH, xpath)
        downloadButton.click()
        time.sleep(5)
        logging.info(appInfo.app_name + (":下载agc_debug证书完成" if profileName == "agc_debug" else ":下载agc_release证书完成"))
    except Exception:
        logging.error(appInfo.app_name + (":下载agc_debug证书失败" if profileName == "agc_debug" else ":下载agc_release证书失败"))

def getAppId(driver, appInfo):
    try:
        switchToNewIframe(driver)
        addButton = driver.find_element(By.XPATH, "//span[@class= 'el-link__inner' and text()='" + appInfo.app_name + "']")
        addButton.click()
        time.sleep(3)

        addIdElem = driver.find_element(By.XPATH, "//div[text() = 'APP ID：']/following-sibling::div[1]")
        return addIdElem.text
    except Exception:
        logging.error(appInfo.app_name + ":获取appId失败")
        return None

def logout(driver):
    try:
        driver.switch_to.default_content()

        userBox = driver.find_element(By.CLASS_NAME, "user-box")
        userBox.click()
        time.sleep(2)
        logoutButton = driver.find_element(By.CLASS_NAME, "btn-logout")
        logoutButton.click()
        logging.info("AGC注销成功")
    except Exception:
        logging.error("AGC注销失败：检查网络状态")
        raise

def saveProperties(appInfo,userConfig):
    try:
        save_config_to_properties(appInfo,userConfig)
        logging.info(appInfo.app_name + "：保存properties完成")
    except Exception:
        logging.error(appInfo.app_name + "：保存properties失败:检查download文件夹是否存在")
        raise

def switchToNewIframe(driver):
    driver.switch_to.default_content()
    frameElement = driver.find_element(By.XPATH, "//iframe[@id='mainIframeView']")
    driver.switch_to.frame(frameElement)